package com.example.petplanet.intercept;

import com.example.petplanet.config.AppConfig;
import com.example.petplanet.util.JWTUtil;
import com.example.petplanet.util.SecureEncryptionUtil;
import io.jsonwebtoken.Claims;
import jakarta.websocket.HandshakeResponse;
import jakarta.websocket.server.HandshakeRequest;
import jakarta.websocket.server.ServerEndpointConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Component
public class WebSocketHandshakeInterceptor {

    private final AppConfig appConfig;

    private final StringRedisTemplate stringRedisTemplate;

    public WebSocketHandshakeInterceptor(AppConfig appConfig, StringRedisTemplate stringRedisTemplate) {
        this.appConfig = appConfig;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    public void handleHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        try {
            Map<String, List<String>> headers = request.getHeaders();
            List<String> authHeaders = headers.get("Authorization");
            if (authHeaders == null || authHeaders.isEmpty()) {
                throw new IllegalArgumentException("Token missing");
            }
            String token = authHeaders.get(0);
            Claims claims = parseToken(token, appConfig.getJwtSecret());
            String userIdentity = claims.getSubject();
            if (userIdentity == null) {
                throw new IllegalArgumentException("Token validation failed");
            }
            String userIdStr = decryptUserIdentity(userIdentity, appConfig.getAppid(), appConfig.getSecret());
            String key = "app:user:" + userIdStr;
            Map<Object, Object> tokenMap = stringRedisTemplate.opsForHash().entries(key);
            String redisToken = (String) tokenMap.get("token");
            if (redisToken == null ||!redisToken.equals(token.substring(7))) {
                throw new IllegalArgumentException("Token not match");
            }
            sec.getUserProperties().put("userId", userIdStr);
        } catch (Exception e) {
            throw new IllegalArgumentException("Handshake failed: " + e.getMessage(), e);
        }
    }

    private Claims parseToken(String token, String secret) throws Exception {
        return JWTUtil.parseToken(token, secret);
    }

    private String decryptUserIdentity(String userIdentity, String appid, String appSecret) throws Exception {
        return SecureEncryptionUtil.decrypt(userIdentity, appid, appSecret);
    }
}
